<template>
  <div class="home-container">
    <!-- Lyrics Input Container -->
    <div class="lyrics-container">
      <h2>歌词输入</h2>
      <el-form label-position="top">
        <el-form-item label="粤语拼音输入">
          <el-input
            type="textarea"
            v-model="lyricForm.pinyin"
            rows="5"
            placeholder="请输入粤语拼音"
          />
        </el-form-item>
        
        <el-form-item label="歌词输入">
          <div class="lyrics-input-container">
            <el-input
              type="textarea"
              v-model="lyricForm.lyrics"
              rows="5"
              placeholder="请输入歌词"
            />
            <div class="upload-lrc-btn">
              <el-upload
                class="upload-lrc"
                action="#"
                :auto-upload="false"
                :show-file-list="false"
                :on-change="handleLrcUpload"
                accept=".lrc"
              >
                <el-button 
                  type="primary" 
                  size="small" 
                  icon="Upload"
                  title="上传LRC文件"
                >
                  上传LRC
                </el-button>
              </el-upload>
            </div>
          </div>
        </el-form-item>
        
        <el-form-item label="谐音输入">
          <el-input
            type="textarea"
            v-model="lyricForm.phonetic"
            rows="5"
            placeholder="请输入谐音"
          />
        </el-form-item>
        
        <el-form-item>
          <el-button type="primary" @click="startParse">开始解析</el-button>
        </el-form-item>
      </el-form>
    </div>
    
    <!-- Parse Preview Container -->
    <div class="parse-preview-container">
      <!-- 时间调整按钮 -->
      <div class="time-adjust-controls">
        <el-button-group>
          <el-button 
            type="primary" 
            size="small" 
            icon="Plus"
            @click="adjustAllTimes(100)"
            :disabled="!hasAdjustableLines"
          >
            +100ms
          </el-button>
          <el-button 
            type="warning" 
            size="small" 
            icon="Minus"
            @click="adjustAllTimes(-100)"
            :disabled="!hasAdjustableLines"
          >
            -100ms
          </el-button>
        </el-button-group>
      </div>
      
      <!-- 下载进度指示器 -->
      <div v-if="downloadStatus.downloading" class="download-progress-container">
        <el-progress 
          :percentage="Math.round((downloadStatus.completed / downloadStatus.total) * 100)" 
          :status="downloadStatus.errors.length > 0 ? 'exception' : 'success'"
          :stroke-width="15"
        >
          <span>正在检查并下载拼音音频文件: {{ downloadStatus.completed }}/{{ downloadStatus.total }}</span>
        </el-progress>
        
        <!-- 服务器状态指示器 -->
        <div class="server-status">
          <el-tag
            :type="serverStatus === 'online' ? 'success' : serverStatus === 'checking' ? 'info' : 'danger'"
            effect="dark"
            size="small"
          >
            服务器状态: {{ serverStatusText }}
          </el-tag>
          <el-button 
            type="primary" 
            size="small" 
            :disabled="serverStatus === 'checking'"
            @click="checkServerStatus"
          >
            检查服务器
          </el-button>
        </div>
        
        <!-- 下载日志区域 -->
        <div class="download-logs">
          <p class="log-title">下载日志 (最近5条):</p>
          <div class="log-container">
            <p v-for="(log, index) in downloadLogs.slice(-5).reverse()" :key="index" :class="getLogClass(log)">
              {{ log }}
            </p>
          </div>
          <el-alert
            v-if="serverStatus !== 'online'"
            title="注意：由于浏览器安全限制，文件会下载到您的浏览器默认下载文件夹，而不是直接保存到项目src/mp3目录"
            type="warning"
            :closable="false"
            show-icon
          />
          <el-alert
            v-else
            title="下载服务器已连接，文件将直接保存到项目的src/mp3目录"
            type="success"
            :closable="false"
            show-icon
          />
        </div>
      </div>
      
      <h2>解析预览</h2>
      
      <div class="preview-buttons" v-if="parsedData && parsedData.length > 0">
        <el-button 
          class="copy-btn" 
          type="primary" 
          size="small" 
          icon="DocumentCopy"
          @click="copyLyrics">
          复制歌词
        </el-button>
        <el-button 
          type="success" 
          size="small" 
          icon="Download"
          @click.prevent="downloadPinyinFiles">
          下载拼音文件
        </el-button>
      </div>
      <div class="preview-content" v-if="parsedData && parsedData.length > 0">
        <div v-for="(line, index) in parsedData" :key="index" class="parsed-line" :class="{'time-warning': isTimeExceeded(line), 'empty-line': line.isEmptyLine}">
          <template v-if="line.isSection">
            <div class="section-marker">
              {{ line.sectionText }}
              <el-button 
                type="danger" 
                circle 
                size="small" 
                icon="Delete"
                @click="deleteLyricLine(index)"
                title="删除此分段标记"
                class="delete-section-btn"
                style="position: absolute; right: 10px;">
              </el-button>
            </div>
          </template>
          <template v-else-if="line.isEmptyLine">
            <el-button 
              class="section-btn" 
              size="small"
              type="info"
              @click="addSection(index)"
            >
              分段
            </el-button>
            <div class="line-number">{{ getActualLineNumber(index) }}</div>
            <div class="empty-line-content">
              <div class="aligned-content">
                <div class="unit-grid">
                  <div v-if="line.pinyin && line.pinyin.trim()" class="empty-line-text">
                    拼音: {{ line.pinyin }}
                  </div>
                  <div v-if="line.phonetic && line.phonetic.trim()" class="empty-line-text">
                    谐音: {{ line.phonetic }}
                  </div>
                  <div v-if="!line.pinyin?.trim() && !line.phonetic?.trim()" class="empty-line-placeholder">
                    [空行]
                  </div>
                </div>
              </div>
            </div>
            <div class="play-button-container" v-if="line.pinyin && line.pinyin.trim()">
              <el-button 
                type="primary" 
                circle 
                size="small" 
                icon="Headset"
                @click.prevent="playPinyinLine(index)"
                title="播放整行粤语拼音"
                class="pinyin-play-btn">
              </el-button>
              <el-button 
                type="danger" 
                circle 
                size="small" 
                icon="Delete"
                @click="deleteLyricLine(index)"
                title="删除此行"
                class="delete-btn">
              </el-button>
            </div>
            <div class="play-button-container" v-else>
              <el-button 
                type="danger" 
                circle 
                size="small" 
                icon="Delete"
                @click="deleteLyricLine(index)"
                title="删除此行"
                class="delete-btn">
              </el-button>
            </div>
          </template>
          <template v-else>
            <el-button 
              class="section-btn" 
              size="small"
              type="info"
              @click="addSection(index)"
            >
              分段
            </el-button>
            <div class="line-number">{{ getActualLineNumber(index) }}</div>
            <div class="time-container">
              <div class="time-row">{{ line.time }}</div>
              <el-button 
                class="time-capture-btn"
                type="primary" 
                size="small" 
                icon="Timer"
                @click="captureTime(index, 'start')"
                :disabled="!isAudioPlaying">
                采集
              </el-button>
              <div class="time-separator">-</div>
              <div class="time-row end-time">{{ getEndTime(index) }}</div>
              <el-button 
                class="time-capture-btn"
                type="success" 
                size="small" 
                icon="Timer"
                @click="captureTime(index, 'end')"
                :disabled="!isAudioPlaying">
                采集
              </el-button>
            </div>
            <div class="line-content">
              <div class="aligned-content">
                <div class="unit-grid">
                  <div v-for="(unit, i) in line.alignedUnits" :key="i" class="unit-pair">
                    <div class="pinyin-unit" @click="playPinyinAudio(unit.pinyin)">{{ unit.pinyin }}</div>
                    <div class="lyric-unit" @click="playPinyinAudio(unit.pinyin)">{{ unit.lyric }}</div>
                    <div class="phonetic-unit">{{ unit.phonetic }}</div>
                  </div>
                </div>
              </div>
            </div>
            <div class="play-button-container">
              <el-button 
                type="primary" 
                circle 
                size="small" 
                icon="Headset"
                @click.prevent="playPinyinLine(index)"
                :disabled="!parsedData[index].alignedUnits || parsedData[index].alignedUnits.length === 0"
                title="播放整行粤语拼音"
                class="pinyin-play-btn">
              </el-button>
              <el-button 
                type="success" 
                circle 
                size="small" 
                icon="VideoPlay"
                @click="playLyricLine(index)"
                :disabled="!vocalUrl"
                title="播放人声">
              </el-button>
              <el-button 
                type="danger" 
                circle 
                size="small" 
                icon="Delete"
                @click="deleteLyricLine(index)"
                title="删除此行"
                class="delete-btn">
              </el-button>
            </div>
          </template>
        </div>
      </div>
      <div v-else class="empty-preview">
        <el-empty description="暂无解析数据" />
      </div>
    </div>
    
    <!-- Audio Player for Line Playback (Hidden) -->
    <audio ref="audioPlayer" :src="vocalUrl" @timeupdate="onTimeUpdate"></audio>
    
    <!-- Parameters Container -->
    <div class="parameters-container">
      <h2>参数设置</h2>
      <el-form :model="songForm" label-position="top">
        <el-form-item label="标题">
          <el-input v-model="songForm.title" placeholder="请输入标题" />
        </el-form-item>
        
        <el-form-item label="作词">
          <el-input v-model="songForm.lyricist" placeholder="请输入作词" />
        </el-form-item>
        
        <el-form-item label="作曲">
          <el-input v-model="songForm.composer" placeholder="请输入作曲" />
        </el-form-item>
        
        <el-form-item label="歌手">
          <el-input v-model="songForm.singer" placeholder="请输入歌手" />
        </el-form-item>
        
        <el-form-item label="人声音频">
          <el-upload
            class="upload-demo"
            action="#"
            :http-request="uploadVocal"
            :on-preview="handlePreview"
            :on-remove="handleRemoveVocal"
            :file-list="vocalFiles"
            :auto-upload="true"
            accept=".mp3"
          >
            <el-button type="primary">选择文件</el-button>
            <template #tip>
              <div class="el-upload__tip">仅支持 mp3 格式文件</div>
            </template>
          </el-upload>
          <div v-if="vocalUrl" class="audio-player">
            <audio controls :src="vocalUrl"></audio>
          </div>
        </el-form-item>
        
        <el-form-item label="伴奏音频">
          <el-upload
            class="upload-demo"
            action="#"
            :http-request="uploadInstrumental"
            :on-preview="handlePreview"
            :on-remove="handleRemoveInstrumental"
            :file-list="instrumentalFiles"
            :auto-upload="true"
            accept=".mp3"
          >
            <el-button type="primary">选择文件</el-button>
            <template #tip>
              <div class="el-upload__tip">仅支持 mp3 格式文件</div>
            </template>
          </el-upload>
          <div v-if="instrumentalUrl" class="audio-player">
            <audio controls :src="instrumentalUrl"></audio>
          </div>
        </el-form-item>
        
        <el-form-item>
          <el-button type="primary" @click="saveData">保存</el-button>
          <el-button type="success" @click="saveAndPublish">保存并发布</el-button>
        </el-form-item>
      </el-form>
    </div>
    

  </div>
</template>

<script setup>
import { ref, reactive, watch, computed, onMounted } from 'vue';
import { ElMessage } from 'element-plus';

// 页面加载时恢复表单数据
onMounted(() => {
  try {
    const savedData = localStorage.getItem('formBackup');
    if (savedData) {
      const parsedData = JSON.parse(savedData);
      
      // 恢复表单数据
      lyricForm.pinyin = parsedData.pinyin || '';
      lyricForm.lyrics = parsedData.lyrics || '';
      lyricForm.phonetic = parsedData.phonetic || '';
      songForm.title = parsedData.title || '';
      songForm.lyricist = parsedData.lyricist || '';
      songForm.composer = parsedData.composer || '';
      songForm.singer = parsedData.singer || '';
      
      // 如果有已解析的数据，也恢复它
      if (parsedData.parsedData) {
        try {
          const restoredParsedData = JSON.parse(parsedData.parsedData);
          if (restoredParsedData && restoredParsedData.length > 0) {
            // 直接恢复解析后的数据
            parsedData.value = restoredParsedData;
            setTimeout(() => {
              ElMessage.info('已从上次中断的下载恢复表单数据和解析结果');
            }, 500);
          }
        } catch (e) {
          console.error('解析已保存的数据时出错:', e);
        }
      }
      
      // 清除localStorage，因为已经恢复了数据
      localStorage.removeItem('formBackup');
    }
  } catch (e) {
    console.error('从localStorage恢复数据时出错:', e);
  }
});

// Lyrics form data
const lyricForm = reactive({
  pinyin: '',
  lyrics: '',
  phonetic: ''
});

// Parsed data
const parsedData = ref(null);

// 监听粤语拼音输入，自动剔除汉字
watch(() => lyricForm.pinyin, (newValue) => {
  if (newValue) {
    // 使用正则表达式移除所有汉字（Unicode范围：\u4e00-\u9fff）
    const filteredPinyin = newValue.replace(/[\u4e00-\u9fff]/g, '');
    
    // 如果过滤后的内容与原来不同，更新拼音
    if (filteredPinyin !== newValue) {
      lyricForm.pinyin = filteredPinyin;
      ElMessage.info('已自动移除拼音输入中的汉字');
    }
  }
  
  // 如果歌词已经输入，则自动解析
  if (lyricForm.lyrics && lyricForm.lyrics.trim()) {
    parseData();
  }
});

// 监听谐音输入，自动触发解析
watch(() => lyricForm.phonetic, (newValue) => {
  // 如果歌词已经输入，则自动解析
  if (lyricForm.lyrics && lyricForm.lyrics.trim()) {
    parseData();
  }
});

// 监听歌词输入变化，过滤不符合[X:X.X]格式的行并自动解析
watch(() => lyricForm.lyrics, (newValue) => {
  if (newValue) {
    // 分割成行
    const lines = newValue.split('\n');
    
    // 提取歌曲信息
    lines.forEach(line => {
      const trimmedLine = line.trim();
      
      // 移除时间标记 [X:X.X] 部分后再进行匹配
      const contentWithoutTimestamp = trimmedLine.replace(/^\[\d+:\d+\.\d+\]/, '').trim();
      
      // 匹配 "标题 - 歌手" 格式
      const titleArtistMatch = contentWithoutTimestamp.match(/^(.+?)\s*-\s*(.+)$/);
      if (titleArtistMatch) {
        const title = titleArtistMatch[1].trim();
        const singer = titleArtistMatch[2].trim();
        if (title) songForm.title = title;
        if (singer) songForm.singer = singer;
      }
      
      // 匹配 "词：作词人" 格式
      const lyricistMatch = contentWithoutTimestamp.match(/^词[：:]\s*(.+)$/);
      if (lyricistMatch) {
        const lyricist = lyricistMatch[1].trim();
        if (lyricist) songForm.lyricist = lyricist;
      }
      
      // 匹配 "曲：作曲人" 格式
      const composerMatch = contentWithoutTimestamp.match(/^曲[：:]\s*(.+)$/);
      if (composerMatch) {
        const composer = composerMatch[1].trim();
        if (composer) songForm.composer = composer;
      }
    });
    
    // 只保留符合[X:X.X]格式的行或空行，X是数字
    const filteredLines = lines.filter(line => {
      // 空行保留
      if (line.trim() === '') return true;
      // 使用正则表达式匹配[数字:数字.数字]格式
      return /^\[\d+:\d+\.\d+\]/.test(line.trim());
    });
    // 如果过滤后的行数与原来不同，更新歌词
    if (filteredLines.length !== lines.length) {
      lyricForm.lyrics = filteredLines.join('\n');
      ElMessage.info('已自动过滤不符合时间标记格式的行');
    }
    
    // 自动解析歌词
    parseData();
  }
}, { immediate: true });

// Song form data
const songForm = reactive({
  title: '',
  lyricist: '',
  composer: '',
  singer: ''
});

// Audio files
const vocalFiles = ref([]);
const instrumentalFiles = ref([]);
const vocalUrl = ref('');
const instrumentalUrl = ref('');

// Audio player reference and state
const audioPlayer = ref(null);
const currentPlayingIndex = ref(-1);
const isPlaying = ref(false);

// 添加全局音频播放状态
const isAudioPlaying = ref(false);

// 添加全局音频控制器
const audioManager = {
  activeAudios: [],
  
  // 停止所有正在播放的音频
  stopAll() {
    this.activeAudios.forEach(audio => {
      try {
        audio.pause();
        audio.currentTime = 0;
      } catch (error) {
        console.error('停止音频时出错:', error);
      }
    });
    this.activeAudios = [];
  },
  
  // 添加音频到管理器
  add(audio) {
    this.activeAudios.push(audio);
  },
  
  // 从管理器中移除音频
  remove(audio) {
    const index = this.activeAudios.indexOf(audio);
    if (index !== -1) {
      this.activeAudios.splice(index, 1);
    }
  }
};

// Parse lyrics function
const parseData = () => {
  if (!lyricForm.lyrics.trim()) {
    parsedData.value = [];
    return;
  }
  
  // 分割歌词、拼音和谐音为行（保留空行）
  const lines = lyricForm.lyrics.split('\n');
  const pinyinLines = lyricForm.pinyin.split('\n');
  const phoneticLines = lyricForm.phonetic.split('\n');
  
  // 解析每一行，提取时间标记和歌词内容，并添加拼音和谐音
  const tempParsedData = [];
  
  // 首先添加第一段标记
  tempParsedData.push({
    isSection: true,
    sectionText: '第1段'
  });
  
  lines.forEach((line, index) => {
    // 处理空行的情况
    if (line.trim() === '') {
      // 对应的拼音行和谐音行
      const pinyin = pinyinLines[index] || '';
      const phonetic = phoneticLines[index] || '';
      
      tempParsedData.push({
        time: '00:00.00',
        endTime: '00:00.00',
        lyrics: '',
        pinyin: pinyin,
        phonetic: phonetic,
        alignedUnits: [],
        isEmptyLine: true  // 标记为空行
      });
      return;
    }
    
    // 匹配时间标记 [X:X.X]
    const timeMatch = line.match(/^\[(\d+:\d+\.\d+)\]/);
    
    let time, lyrics;
    if (timeMatch) {
      time = timeMatch[1]; // 提取时间部分
      // 提取歌词内容（时间标记后面的部分）
      lyrics = line.substring(timeMatch[0].length).trim();
    } else {
      // 如果没有匹配到时间标记，使用原行作为歌词
      time = '00:00.00';
      lyrics = line.trim();
    }
    
    // 对应的拼音行和谐音行
    const pinyin = pinyinLines[index] || '';
    const phonetic = phoneticLines[index] || '';
    
    // 将拼音按空格分割成单位
    const pinyinUnits = pinyin ? pinyin.split(' ').filter(unit => unit.trim()) : [];
    
    // 将歌词按规则分割：汉字单独一个单位，连续的非汉字作为一个单位
    let lyricUnits = [];
    if (lyrics) {
      // 使用正则表达式匹配汉字或连续的非汉字
      const matches = lyrics.match(/[\u4e00-\u9fff]|[^\u4e00-\u9fff\s]+/g);
      lyricUnits = matches || [];
    }
    
    // 将谐音按规则分割：汉字单独一个单位，连续的非汉字作为一个单位
    let phoneticUnits = [];
    if (phonetic) {
      // 使用正则表达式匹配汉字或连续的非汉字
      const matches = phonetic.match(/[\u4e00-\u9fff]|[^\u4e00-\u9fff\s]+/g);
      phoneticUnits = matches || [];
    }
    
    // 创建对齐后的单元对，处理三种内容的单位数量不一致的情况
    const alignedUnits = [];
    const maxLength = Math.max(pinyinUnits.length, lyricUnits.length, phoneticUnits.length);
    
    for (let i = 0; i < maxLength; i++) {
      alignedUnits.push({
        pinyin: i < pinyinUnits.length ? pinyinUnits[i] : '',
        lyric: i < lyricUnits.length ? lyricUnits[i] : '',
        phonetic: i < phoneticUnits.length ? phoneticUnits[i] : ''
      });
    }
    
    // 添加一个单独的结束时间字段，特别是为了处理最后一行
    let endTime = '';
    if (index < lines.length - 1) {
      // 如果不是最后一行，尝试获取下一行的时间
      const nextTimeMatch = lines[index + 1].match(/^\[(\d+:\d+\.\d+)\]/);
      endTime = nextTimeMatch ? nextTimeMatch[1] : '';
    } else {
      // 最后一行的结束时间初始化为开始时间+15秒
      const [minutes, rest] = time.split(':');
      const [seconds, ms] = rest.split('.');
      
      // 转换为总毫秒数
      let totalMs = parseInt(minutes) * 60 * 1000 + parseInt(seconds) * 1000 + parseInt(ms);
      
      // 加15秒
      totalMs += 15 * 1000;
      
      // 转换回时间字符串格式
      const newMinutes = Math.floor(totalMs / (60 * 1000));
      const newSeconds = Math.floor((totalMs % (60 * 1000)) / 1000);
      const newMs = totalMs % 1000;
      
      endTime = `${newMinutes.toString().padStart(2, '0')}:${newSeconds.toString().padStart(2, '0')}.${newMs.toString().padStart(3, '0')}`;
    }
    
    tempParsedData.push({
      time,
      endTime, // 存储结束时间
      lyrics,
      pinyin,
      phonetic,
      alignedUnits
    });
  });
  
  parsedData.value = tempParsedData;
  
  console.log('解析数据:', parsedData.value);
};

// 时间字符串转换为秒数
const timeToSeconds = (timeStr) => {
  const [minutes, rest] = timeStr.split(':');
  const [seconds, milliseconds] = rest.split('.');
  return parseInt(minutes) * 60 + parseInt(seconds) + parseInt(milliseconds) / 1000;
};

// 播放指定行的歌词
const playLyricLine = (index) => {
  // 如果是分段标记或空行，不执行任何操作
  if (parsedData.value[index].isSection || parsedData.value[index].isEmptyLine) {
    return;
  }
  
  if (!vocalUrl.value || !parsedData.value || index >= parsedData.value.length) {
    ElMessage.warning('没有可播放的音频或歌词');
    return;
  }
  
  // 停止当前播放
  if (isPlaying.value) {
    audioPlayer.value.pause();
    isPlaying.value = false;
    
    // 如果是点击同一行，则只是停止播放并返回
    if (currentPlayingIndex.value === index) {
      currentPlayingIndex.value = -1;
      return;
    }
  }
  
  // 停止所有其他音频播放
  audioManager.stopAll();
  
  currentPlayingIndex.value = index;
  
  // 计算开始时间和结束时间
  const startTime = timeToSeconds(parsedData.value[index].time);
  const endTime = timeToSeconds(parsedData.value[index].endTime);
  
  // 设置音频播放位置并开始播放
  audioPlayer.value.currentTime = startTime;
  audioPlayer.value.play().then(() => {
    isPlaying.value = true;
    ElMessage.success(`正在播放第${getActualLineNumber(index)}行歌词`);
  }).catch(error => {
    console.error('播放失败:', error);
    ElMessage.error('播放失败，请检查音频文件');
    isPlaying.value = false;
    currentPlayingIndex.value = -1;
  });
};

// 采集时间函数
const captureTime = (index, position) => {
  // 如果是分段标记或空行，不执行任何操作
  if (parsedData.value[index].isSection || parsedData.value[index].isEmptyLine) {
    return;
  }
  
  if (!audioPlayer.value || !isAudioPlaying.value) {
    ElMessage.warning('请先播放音频');
    return;
  }
  
  // 获取当前音频播放时间
  const currentTime = audioPlayer.value.currentTime;
  
  // 转换为格式化时间字符串
  const minutes = Math.floor(currentTime / 60);
  const seconds = Math.floor(currentTime % 60);
  const milliseconds = Math.floor((currentTime % 1) * 1000);
  
  const formattedTime = `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}.${milliseconds.toString().padStart(3, '0')}`;
  
  // 根据position更新对应位置的时间
  if (position === 'start') {
    // 更新开始时间
    parsedData.value[index].time = formattedTime;
    
    // 如果是最后一行，也需要更新结束时间（开始时间+15秒）
    if (index === parsedData.value.length - 1 || parsedData.value[index + 1].isSection) {
      const totalMs = minutes * 60 * 1000 + seconds * 1000 + milliseconds + 15 * 1000;
      const endMinutes = Math.floor(totalMs / (60 * 1000));
      const endSeconds = Math.floor((totalMs % (60 * 1000)) / 1000);
      const endMs = totalMs % 1000;
      
      parsedData.value[index].endTime = `${endMinutes.toString().padStart(2, '0')}:${endSeconds.toString().padStart(2, '0')}.${endMs.toString().padStart(3, '0')}`;
    }
    
    ElMessage.success(`第${getActualLineNumber(index)}行开始时间已更新为 ${formattedTime}`);
  } else if (position === 'end') {
    // 只更新当前行的结束时间，不影响下一行
    parsedData.value[index].endTime = formattedTime;
    ElMessage.success(`第${getActualLineNumber(index)}行结束时间已更新为 ${formattedTime}`);
  }
};

// 监听音频播放进度
const onTimeUpdate = () => {
  if (!isPlaying.value || currentPlayingIndex.value === -1) return;
  
  const currentTime = audioPlayer.value.currentTime;
  const index = currentPlayingIndex.value;
  
  // 使用存储的结束时间
  const endTime = timeToSeconds(parsedData.value[index].endTime);
  
  // 如果当前时间超过了结束时间，停止播放
  if (currentTime >= endTime) {
    audioPlayer.value.pause();
    isPlaying.value = false;
    currentPlayingIndex.value = -1;
  }
};

// 下载状态追踪
const downloadStatus = reactive({
  total: 0,
  completed: 0,
  downloading: false,
  errors: []
});

// 存储下载日志
const downloadLogs = ref([]);

// 根据日志内容返回样式类
const getLogClass = (log) => {
  if (log.includes('[本地存在]') || log.includes('[缓存命中]') || log.includes('[下载完成]')) {
    return 'success';
  } else if (log.includes('[本地缺失]') || log.includes('[创建下载]')) {
    return 'warning';
  } else if (log.includes('[下载错误]') || log.includes('[远程缺失]') || log.includes('[下载失败]') || log.includes('[处理错误]')) {
    return 'exception';
  }
  return '';
};

// 添加开始解析按钮的点击事件处理函数
const startParse = async () => {
  parseData();
  if (parsedData.value && parsedData.value.length > 0) {
    ElMessage.success('解析完成');
  } else {
    ElMessage.warning('没有可解析的内容');
  }
};

// 下载拼音文件函数
const downloadPinyinFiles = async (event) => {
  // 防止页面刷新
  if (event) {
    event.preventDefault();
  }
  
  if (!parsedData.value || parsedData.value.length === 0) {
    ElMessage.warning('没有可解析的内容，请先点击"开始解析"');
    return;
  }
  
  // 备份表单数据到localStorage，防止刷新导致丢失
  const formBackup = {
    pinyin: lyricForm.pinyin,
    lyrics: lyricForm.lyrics,
    phonetic: lyricForm.phonetic,
    title: songForm.title,
    lyricist: songForm.lyricist,
    composer: songForm.composer,
    singer: songForm.singer,
    parsedData: JSON.stringify(parsedData.value)
  };
  
  // 保存到localStorage
  try {
    localStorage.setItem('formBackup', JSON.stringify(formBackup));
  } catch (e) {
    console.error('无法保存表单数据到localStorage:', e);
  }
  
  // 收集所有需要的拼音单元
  const allPinyinUnits = new Set();
  parsedData.value.forEach(line => {
    if (!line.isSection && line.alignedUnits) {
      line.alignedUnits.forEach(unit => {
        if (unit.pinyin && unit.pinyin.trim()) {
          allPinyinUnits.add(unit.pinyin.trim());
        }
      });
    }
  });
  
  // 设置下载状态
  downloadStatus.total = allPinyinUnits.size;
  downloadStatus.completed = 0;
  downloadStatus.downloading = true;
  downloadStatus.errors = [];
  downloadLogs.value = []; // 清空之前的日志
  
  // 显示正在检查文件的消息
  ElMessage.info(`正在检查并下载所需的${allPinyinUnits.size}个拼音音频文件...`);
  
  // 首先尝试使用批量下载API
  try {
    // 检查服务器是否在线
    await checkServerStatus();
    
    if (serverStatus.value === 'online') {
      // 服务器在线，使用批量下载API
      downloadLogs.value.push(`[批量下载] 使用服务器批量下载 ${allPinyinUnits.size} 个拼音文件`);
      
      // 将Set转换为数组
      const pinyinArray = Array.from(allPinyinUnits);
      
      try {
        // 发送批量下载请求
        const batchResponse = await fetch(`${API_BASE_URL}/api/download-multiple`, {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({ pinyinList: pinyinArray }),
        });
        
        if (batchResponse.ok) {
          const batchData = await batchResponse.json();
          if (batchData.success) {
            downloadLogs.value.push(`[批量请求] 服务器已接收批量下载请求，正在后台处理`);
            ElMessage.success('服务器已接收下载请求，将在后台处理');
            
            // 服务器会在后台处理下载，我们仍然需要逐个检查文件
            // 但我们可以等待一会儿，让服务器有时间开始下载
            await new Promise(resolve => setTimeout(resolve, 1000));
          }
        } else {
          const errorText = await batchResponse.text();
          downloadLogs.value.push(`[批量下载错误] 服务器返回错误: ${batchResponse.status}, ${errorText.substring(0, 50)}`);
          console.error('批量下载请求错误:', batchResponse.status, errorText);
        }
      } catch (fetchError) {
        downloadLogs.value.push(`[批量下载失败] 请求错误: ${fetchError.message}`);
        console.error('批量下载请求失败:', fetchError);
      }
    } else {
      downloadLogs.value.push(`[服务器离线] 下载服务器不可用，将使用浏览器下载方式`);
      ElMessage.warning('下载服务器不可用，将使用浏览器下载');
    }
  } catch (serverError) {
    downloadLogs.value.push(`[服务器错误] 无法使用批量下载: ${serverError.message}`);
    console.error('批量下载错误:', serverError);
  }
  
  // 继续逐个检查和下载文件
  try {
    let downloadCount = 0;
    
    // 使用一个更强的防抖动措施，确保页面不会刷新
    window.onbeforeunload = function() {
      return "下载正在进行中，离开页面将中断下载。确定要离开吗？";
    };
    
    for (const pinyin of allPinyinUnits) {
      const result = await checkAndDownloadPinyinFile(pinyin);
      downloadStatus.completed++;
      
      if (result === true) {
        // 文件已存在
      } else if (result === 'downloaded') {
        // 文件被下载
        downloadCount++;
      } else {
        // 下载失败
        downloadStatus.errors.push(pinyin);
      }
      
      // 每完成5个文件就更新一次状态消息
      if (downloadStatus.completed % 5 === 0 || downloadStatus.completed === downloadStatus.total) {
        ElMessage.info(`正在处理：已完成 ${downloadStatus.completed}/${downloadStatus.total} 个文件`);
      }
      
      // 短暂等待
      await new Promise(resolve => setTimeout(resolve, 100));
    }
    
    // 下载完成后移除onbeforeunload处理器
    window.onbeforeunload = null;
    
    downloadStatus.downloading = false;
    
    if (downloadCount > 0) {
      ElMessage.success(`所有拼音音频文件检查完成，新下载了 ${downloadCount} 个文件`);
    } else {
      ElMessage.success('所有拼音音频文件检查完成，无需下载新文件');
    }
    
    if (downloadStatus.errors.length > 0) {
      ElMessage.warning(`有 ${downloadStatus.errors.length} 个拼音文件下载失败`);
      console.error('下载失败的拼音:', downloadStatus.errors);
    }
    
    // 清除localStorage中的备份，因为不再需要它
    localStorage.removeItem('formBackup');
  } catch (error) {
    downloadStatus.downloading = false;
    console.error('下载音频文件时出错:', error);
    ElMessage.error('部分拼音音频文件下载失败');
    
    // 确保发生错误时也移除onbeforeunload处理器
    window.onbeforeunload = null;
  }
};

// 缓存已下载的音频文件
const pinyinCache = new Map();

// 后端API地址
const API_BASE_URL = 'http://localhost:3002';

// 服务器状态
const serverStatus = ref('unknown'); // 'online', 'offline', 'checking', 'unknown'
const serverStatusText = computed(() => {
  switch (serverStatus.value) {
    case 'online': return '在线';
    case 'offline': return '离线';
    case 'checking': return '检查中...';
    default: return '未知';
  }
});

// 检查服务器状态
const checkServerStatus = async () => {
  serverStatus.value = 'checking';
  downloadLogs.value.push('[检查服务器] 正在检查下载服务器状态');
  
  try {
    const response = await fetch(`${API_BASE_URL}/api/status`, { 
      signal: AbortSignal.timeout(2000) // 2秒超时
    });
    
    if (response.ok) {
      const data = await response.json();
      if (data.status === 'ok') {
        serverStatus.value = 'online';
        downloadLogs.value.push('[服务器状态] 下载服务器在线，文件将直接保存到项目目录');
        ElMessage.success('下载服务器已连接');
      } else {
        serverStatus.value = 'offline';
        downloadLogs.value.push('[服务器状态] 下载服务器返回异常状态');
        ElMessage.error('下载服务器状态异常');
      }
    } else {
      serverStatus.value = 'offline';
      downloadLogs.value.push('[服务器状态] 下载服务器返回错误状态码');
      ElMessage.error('下载服务器返回错误');
    }
  } catch (error) {
    serverStatus.value = 'offline';
    downloadLogs.value.push(`[服务器状态] 无法连接到下载服务器: ${error.message || '连接失败'}`);
    ElMessage.error('无法连接到下载服务器');
  }
};

// 检查并下载单个拼音文件
const checkAndDownloadPinyinFile = async (pinyin) => {
  const addLog = (message) => {
    console.log(message);
    downloadLogs.value.push(message);
  };
  
  try {
    // 如果已经缓存了该拼音，直接返回
    if (pinyinCache.has(pinyin)) {
      addLog(`[缓存命中] 拼音 ${pinyin}.mp3 已在缓存中`);
      return true;
    }
  } catch (error) {
    addLog(`[缓存错误] 检查缓存出错: ${error.message}`);
  }
  
  const localUrl = new URL(`../mp3/${pinyin}.mp3`, import.meta.url).href;
  
  try {
    // 首先通过API检查文件是否已存在于服务器上
    addLog(`[检查服务器] 检查服务器文件: ${pinyin}.mp3`);
    
    try {
      const checkResponse = await fetch(`${API_BASE_URL}/api/check-file/${pinyin}`, {
        signal: AbortSignal.timeout(3000) // 3秒超时
      });
      
      if (checkResponse.ok) {
        const checkData = await checkResponse.json();
        
        if (checkData.exists) {
          addLog(`[服务器存在] 服务器上已有文件: ${pinyin}.mp3`);
          
          // 刷新本地缓存以确保能够访问新文件
          try {
            const refreshResponse = await fetch(localUrl, { 
              method: 'HEAD', 
              cache: 'reload',
              signal: AbortSignal.timeout(2000) // 2秒超时
            });
            
            if (refreshResponse.ok) {
              addLog(`[本地更新] 本地缓存已更新: ${pinyin}.mp3`);
              pinyinCache.set(pinyin, localUrl);
              return true;
            }
          } catch (refreshError) {
            addLog(`[缓存刷新失败] 无法刷新本地缓存: ${refreshError.message}`);
          }
        }
      } else {
        addLog(`[服务器检查失败] 服务器响应错误: ${checkResponse.status}`);
      }
    } catch (checkError) {
      addLog(`[服务器检查错误] 检查文件存在时出错: ${checkError.message}`);
    }
    
    // 如果文件不在服务器上，使用API下载
    addLog(`[请求下载] 请求服务器下载: ${pinyin}.mp3`);
    
    const downloadResponse = await fetch(`${API_BASE_URL}/api/download-pinyin`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ pinyin }),
    });
    
    const downloadData = await downloadResponse.json();
    
    if (downloadData.success) {
      if (downloadData.exists) {
        addLog(`[下载跳过] 文件已存在于服务器: ${pinyin}.mp3`);
      } else {
        addLog(`[下载成功] 服务器已下载文件: ${pinyin}.mp3`);
      }
      
      // 刷新本地缓存以获取新下载的文件
      setTimeout(async () => {
        try {
          const refreshResponse = await fetch(localUrl, { method: 'HEAD', cache: 'reload' });
          if (refreshResponse.ok) {
            addLog(`[本地更新] 本地缓存已更新: ${pinyin}.mp3`);
            pinyinCache.set(pinyin, localUrl);
          }
        } catch (refreshError) {
          console.warn(`刷新缓存错误: ${refreshError.message}`);
        }
      }, 500);
      
      return 'downloaded';
    } else {
      const errorMsg = `[下载失败] 服务器下载失败: ${pinyin}.mp3, ${downloadData.message}`;
      addLog(errorMsg);
      return false;
    }
  } catch (error) {
    const errorMsg = `[请求错误] 无法访问下载服务器: ${error.message || JSON.stringify(error)}`;
    addLog(errorMsg);
    
    // 如果服务器请求失败，尝试旧的浏览器下载方法
    addLog(`[后备下载] 尝试直接浏览器下载: ${pinyin}.mp3`);
    
    try {
      const remoteUrl = `https://shyyp.net/mp3_cantonese/${pinyin}.mp3`;
      addLog(`[远程下载] 尝试从 ${remoteUrl} 下载`);
      
      const response = await fetch(remoteUrl, {
        method: 'GET',
        mode: 'cors',
        cache: 'no-cache',
        headers: {
          'Accept': 'audio/mpeg',
        },
        referrerPolicy: 'no-referrer'
      }).catch(err => {
        const errorMsg = `[下载错误] Fetch 错误: ${err.message || JSON.stringify(err)}`;
        addLog(errorMsg);
        return { ok: false, status: 'network-error' };
      });
      
      if (response.ok) {
        try {
          // 下载文件
          addLog(`[获取内容] 开始获取 ${pinyin}.mp3 文件内容`);
          const blob = await response.blob();
          
          // 添加到缓存
          pinyinCache.set(pinyin, URL.createObjectURL(blob));
          
          // 使用异步下载方式，避免页面刷新
          addLog(`[创建下载] 准备下载 ${pinyin}.mp3 到用户下载文件夹`);
          
          // 创建下载链接但不触发导航
          const a = document.createElement('a');
          a.style.display = 'none';
          a.href = URL.createObjectURL(blob);
          a.download = `${pinyin}.mp3`;
          a.target = '_blank'; // 确保在新标签页打开，不影响当前页面
          
          // 创建文件夹路径
          const saveToPath = '../mp3/';
          
          // 触发下载
          document.body.appendChild(a);
          a.click();
          document.body.removeChild(a);
          
          addLog(`[下载完成] 已触发浏览器下载 ${pinyin}.mp3 - 请手动移动文件到项目目录`);
          
          ElMessage({
            message: `下载服务器不可用，文件已下载到浏览器默认下载文件夹，请手动移动到项目的src/mp3目录`,
            type: 'warning',
            duration: 5000
          });
          
          return 'downloaded'; // 表示已下载新文件
        } catch (blobError) {
          const errorMsg = `[处理错误] 处理文件 ${pinyin}.mp3 时出错: ${blobError.message || JSON.stringify(blobError)}`;
          addLog(errorMsg);
          return false;
        }
      } else {
        const errorMsg = `[远程缺失] 远程音频文件不存在或无法访问: ${pinyin}.mp3, 状态码: ${response.status}`;
        addLog(errorMsg);
        return false;
      }
    } catch (fallbackError) {
      const errorMsg = `[后备失败] 后备下载也失败: ${pinyin}.mp3, ${fallbackError.message || JSON.stringify(fallbackError)}`;
      addLog(errorMsg);
      return false;
    }
  }
};

// File upload handlers
const uploadVocal = (options) => {
  const file = options.file;
  vocalUrl.value = URL.createObjectURL(file);
  vocalFiles.value = [{ name: file.name, url: vocalUrl.value }];
  ElMessage.success('人声音频上传成功');
};

const uploadInstrumental = (options) => {
  const file = options.file;
  instrumentalUrl.value = URL.createObjectURL(file);
  instrumentalFiles.value = [{ name: file.name, url: instrumentalUrl.value }];
  ElMessage.success('伴奏音频上传成功');
};

const handlePreview = (file) => {
  console.log('Preview file', file);
};

const handleRemoveVocal = () => {
  vocalUrl.value = '';
  vocalFiles.value = [];
};

const handleRemoveInstrumental = () => {
  instrumentalUrl.value = '';
  instrumentalFiles.value = [];
};

// Save and publish functions
const saveData = () => {
  if (!songForm.title) {
    ElMessage.warning('请输入歌曲标题');
    return;
  }
  
  // Here would be API call to save the data
  ElMessage.success('歌词数据保存成功');
};

const saveAndPublish = () => {
  if (!songForm.title) {
    ElMessage.warning('请输入歌曲标题');
    return;
  }
  
  // Here would be API call to save and publish
  ElMessage.success('歌词数据保存并发布成功');
};

// 复制纯歌词
const copyLyrics = () => {
  if (parsedData.value && parsedData.value.length > 0) {
    // 提取所有歌词行，不包含时间和序号
    const purelyrics = parsedData.value.map(line => line.lyrics).join('\n');
    
    // 使用剪贴板API复制文本
    navigator.clipboard.writeText(purelyrics)
      .then(() => {
        ElMessage.success('歌词复制成功');
      })
      .catch(err => {
        console.error('复制失败: ', err);
        ElMessage.error('复制失败，请手动复制');
      });
  } else {
    ElMessage.warning('没有可复制的歌词');
  }
};

// 调整所有时间
const adjustAllTimes = (milliseconds) => {
  if (!parsedData.value || parsedData.value.length === 0) {
    return;
  }
  
  // 遍历每一行，调整时间，跳过分段标记和空行
  parsedData.value = parsedData.value.map(line => {
    // 如果是分段标记或空行，直接返回，不做任何处理
    if (line.isSection || line.isEmptyLine) {
      return line;
    }
    
    // 调整开始时间
    const adjustedStartTime = adjustTimeByMs(line.time, milliseconds);
    
    // 调整结束时间
    const adjustedEndTime = adjustTimeByMs(line.endTime, milliseconds);
    
    // 返回更新后的行对象
    return {
      ...line,
      time: adjustedStartTime,
      endTime: adjustedEndTime
    };
  });
  
  // 显示成功消息
  if (milliseconds > 0) {
    ElMessage.success(`所有时间已增加 ${milliseconds}ms`);
  } else {
    ElMessage.success(`所有时间已减少 ${Math.abs(milliseconds)}ms`);
  }
};

// 辅助函数：按毫秒数调整时间
const adjustTimeByMs = (timeStr, milliseconds) => {
  // 解析时间
  const [minutes, rest] = timeStr.split(':');
  const [seconds, ms] = rest.split('.');
  
  // 转换为总毫秒数
  let totalMs = parseInt(minutes) * 60 * 1000 + parseInt(seconds) * 1000 + parseInt(ms);
  
  // 调整时间
  totalMs += milliseconds;
  if (totalMs < 0) totalMs = 0; // 确保时间不为负
  
  // 转换回时间字符串格式
  const newMinutes = Math.floor(totalMs / (60 * 1000));
  const newSeconds = Math.floor((totalMs % (60 * 1000)) / 1000);
  const newMs = totalMs % 1000;
  
  // 格式化时间字符串
  return `${newMinutes.toString().padStart(2, '0')}:${newSeconds.toString().padStart(2, '0')}.${newMs.toString().padStart(3, '0')}`;
};

// 获取结束时间
const getEndTime = (index) => {
  if (!parsedData.value || parsedData.value.length === 0) {
    return '00:00.000';
  }
  
  // 直接返回存储的结束时间
  return parsedData.value[index].endTime;
};

// 计算两个时间点之间的时间差（以毫秒为单位）
const calculateTimeDifference = (startTime, endTime) => {
  // 解析开始时间
  const [startMinutes, startRest] = startTime.split(':');
  const [startSeconds, startMs] = startRest.split('.');
  const startTotalMs = parseInt(startMinutes) * 60 * 1000 + parseInt(startSeconds) * 1000 + parseInt(startMs);
  
  // 解析结束时间
  const [endMinutes, endRest] = endTime.split(':');
  const [endSeconds, endMs] = endRest.split('.');
  const endTotalMs = parseInt(endMinutes) * 60 * 1000 + parseInt(endSeconds) * 1000 + parseInt(endMs);
  
  // 计算差值
  return endTotalMs - startTotalMs;
};

// 检查一行的开始时间和结束时间是否超过10秒
const isTimeExceeded = (line) => {
  if (!line || !line.time || !line.endTime || line.isEmptyLine || line.isSection) return false;
  
  const timeDifference = calculateTimeDifference(line.time, line.endTime);
  return timeDifference > 10000; // 10秒 = 10000毫秒
};

// 导入mp3音频文件
const getAudioUrl = async (pinyin) => {
  const localUrl = new URL(`../mp3/${pinyin}.mp3`, import.meta.url).href;
  
  // 检查本地文件是否存在
  try {
    const response = await fetch(localUrl, { method: 'HEAD' });
    if (response.ok) {
      return localUrl;
    }
  } catch (error) {
    console.log(`本地音频文件不存在: ${pinyin}.mp3`);
  }
  
  // 尝试从远程下载
  try {
    const remoteUrl = `https://shyyp.net/mp3_cantonese/${pinyin}.mp3`;
    const response = await fetch(remoteUrl);
    
    if (response.ok) {
      // 下载文件
      const blob = await response.blob();
      
      // 保存到IndexedDB或使用缓存API
      try {
        // 创建下载链接但不触发导航
        const a = document.createElement('a');
        a.style.display = 'none';
        a.href = URL.createObjectURL(blob);
        a.download = `${pinyin}.mp3`;
        a.target = '_blank'; // 确保在新标签页打开，不影响当前页面
        
        // 创建文件夹路径
        const saveToPath = '../mp3/';
        
        // 触发下载
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        
        ElMessage.success(`已下载音频: ${pinyin}.mp3`);
      } catch (saveError) {
        console.error('保存文件失败:', saveError);
      }
      
      // 返回blob URL用于播放
      return URL.createObjectURL(blob);
    } else {
      console.error(`远程音频文件不存在: ${pinyin}.mp3`);
      return null;
    }
  } catch (error) {
    console.error(`未能加载音频: ${pinyin}.mp3`, error);
    return null;
  }
};

// 播放拼音音频
const playPinyinAudio = async (pinyin) => {
  // 如果拼音为空，不进行任何操作
  if (!pinyin) {
    return;
  }
  
  // 获取去除空格后的拼音
  const cleanPinyin = pinyin.trim();
  
  // 如果清理后的拼音为空，不进行任何操作
  if (!cleanPinyin) {
    return;
  }
  
  try {
    // 在播放新音频前停止所有正在播放的音频
    audioManager.stopAll();
    
    // 获取音频URL (异步)
    const audioUrl = await getAudioUrl(cleanPinyin);
    
    if (!audioUrl) {
      ElMessage.warning(`未找到拼音 "${cleanPinyin}" 的音频文件`);
      return;
    }
    
    // 创建音频对象
    const audio = new Audio(audioUrl);
    
    // 添加到音频管理器
    audioManager.add(audio);
    
    // 监听播放结束，从管理器中移除
    audio.onended = () => {
      audioManager.remove(audio);
    };
    
    // 监听错误，从管理器中移除
    audio.onerror = () => {
      audioManager.remove(audio);
    };
    
    // 播放音频
    audio.play().then(() => {
      console.log(`播放拼音: ${cleanPinyin}`);
    }).catch(error => {
      console.error(`无法播放音频 ${cleanPinyin}.mp3:`, error);
      ElMessage.warning(`未找到拼音 "${cleanPinyin}" 的音频文件`);
      audioManager.remove(audio);
    });
  } catch (error) {
    console.error(`加载音频文件出错: ${error}`);
    ElMessage.error(`加载音频文件出错: ${cleanPinyin}.mp3`);
  }
};

// 播放整行拼音
const playPinyinLine = async (index) => {
  // 停止所有当前播放的音频
  audioManager.stopAll();
  
  // 检查是否是分段标记
  if (parsedData.value[index].isSection) {
    return;
  }
  
  // 使用递归函数顺序播放
  const playSequentially = async (units, currentIndex = 0) => {
    if (currentIndex >= units.length) {
      return; // 全部播放完成
    }
    
    const currentPinyin = units[currentIndex];
    
    try {
      // 获取音频URL
      const audioUrl = await getAudioUrl(currentPinyin);
      
      if (!audioUrl) {
        // 如果获取不到当前拼音的音频，直接跳到下一个
        playSequentially(units, currentIndex + 1);
        return;
      }
      
      // 创建音频对象
      const audio = new Audio(audioUrl);
      
      // 添加到音频管理器
      audioManager.add(audio);
      
      // 监听播放结束事件
      audio.onended = () => {
        // 从管理器中移除
        audioManager.remove(audio);
        // 播放下一个拼音
        playSequentially(units, currentIndex + 1);
      };
      
      // 监听错误事件
      audio.onerror = () => {
        console.error(`播放 ${currentPinyin} 出错，跳到下一个`);
        audioManager.remove(audio);
        playSequentially(units, currentIndex + 1);
      };
      
      // 开始播放
      audio.play();
    } catch (error) {
      console.error(`播放拼音出错: ${error}`);
      // 出错时跳到下一个
      playSequentially(units, currentIndex + 1);
    }
  };
  
  // 特殊处理空行
  if (parsedData.value[index].isEmptyLine) {
    // 如果空行有拼音，播放拼音
    const pinyin = parsedData.value[index].pinyin;
    if (pinyin && pinyin.trim()) {
      const pinyinUnits = pinyin.split(' ').filter(unit => unit.trim());
      if (pinyinUnits.length > 0) {
        ElMessage.info(`开始播放第${getActualLineNumber(index)}行粤语拼音`);
        await playSequentially(pinyinUnits);
      } else {
        ElMessage.warning('该行没有可播放的拼音');
      }
    } else {
      ElMessage.warning('该行没有可播放的拼音');
    }
    return;
  }
  
  // 检查是否有对齐的单元
  if (!parsedData.value[index].alignedUnits || parsedData.value[index].alignedUnits.length === 0) {
    ElMessage.warning('该行没有可播放的拼音');
    return;
  }
  
  // 获取该行所有拼音单元
  const pinyinUnits = parsedData.value[index].alignedUnits
    .map(unit => unit.pinyin)
    .filter(pinyin => pinyin && pinyin.trim());
  
  if (pinyinUnits.length === 0) {
    ElMessage.warning('该行没有可播放的拼音');
    return;
  }
  
  ElMessage.info(`开始播放第${getActualLineNumber(index)}行粤语拼音`);
  
  // 开始顺序播放
  playSequentially(pinyinUnits);
};

// 添加分段功能
const addSection = (index) => {
  // 如果parsedData为空，不执行任何操作
  if (!parsedData.value || parsedData.value.length === 0) {
    return;
  }

  // 计算当前应该是第几段（计算已有的分段标记数量 + 1）
  const existingSections = parsedData.value.filter(item => item.isSection).length;
  const sectionNumber = existingSections + 1;
  
  // 创建新的分段标记对象
  const newSection = {
    isSection: true,
    sectionText: `第${sectionNumber}段`
  };
  
  // 在指定行后插入分段标记
  parsedData.value.splice(index + 1, 0, newSection);
  
  // 提示用户
  ElMessage.success(`在第${index + 1}行后添加了分段标记`);
};

// 获取实际行号（排除分段标记的计数）
const getActualLineNumber = (currentIndex) => {
  if (!parsedData.value) return 0;
  
  // 计算当前索引之前有多少个非分段标记行（包括空行）
  let actualLineCount = 0;
  
  for (let i = 0; i < parsedData.value.length; i++) {
    if (i > currentIndex) break;
    if (!parsedData.value[i].isSection) {
      actualLineCount++;
    }
  }
  
  return actualLineCount;
};

// 检查是否有可调整的非分段行和非空行
const hasAdjustableLines = computed(() => {
  if (!parsedData.value || parsedData.value.length === 0) {
    return false;
  }
  
  return parsedData.value.some(line => !line.isSection && !line.isEmptyLine);
});

// 添加删除行函数
const deleteLyricLine = (index) => {
  // 检查是否有解析数据
  if (!parsedData.value || parsedData.value.length === 0) {
    return;
  }
  
  // 处理删除分段标记的情况
  if (parsedData.value[index].isSection) {
    // 直接从解析数据中删除该分段标记
    parsedData.value.splice(index, 1);
    ElMessage.success('分段标记已删除');
    return;
  }
  
  // 找到当前行在歌词中的实际索引
  const lyricsLines = lyricForm.lyrics.split('\n');
  const pinyinLines = lyricForm.pinyin.split('\n');
  const phoneticLines = lyricForm.phonetic.split('\n');
  
  // 计算实际行号（排除分段标记）
  let actualLineIndex = 0;
  let targetLineIndex = -1;
  
  for (let i = 0; i < index; i++) {
    if (!parsedData.value[i].isSection) {
      actualLineIndex++;
    }
  }
  
  // 确保不超出数组范围
  if (actualLineIndex >= 0 && actualLineIndex < lyricsLines.length) {
    targetLineIndex = actualLineIndex;
  } else {
    ElMessage.error('找不到对应的歌词行');
    return;
  }
  
  // 删除对应的行
  lyricsLines.splice(targetLineIndex, 1);
  
  // 同时删除拼音和谐音中的对应行（如果存在）
  if (targetLineIndex < pinyinLines.length) {
    pinyinLines.splice(targetLineIndex, 1);
  }
  
  if (targetLineIndex < phoneticLines.length) {
    phoneticLines.splice(targetLineIndex, 1);
  }
  
  // 更新表单数据
  lyricForm.lyrics = lyricsLines.join('\n');
  lyricForm.pinyin = pinyinLines.join('\n');
  lyricForm.phonetic = phoneticLines.join('\n');
  
  // 删除解析数据中的对应行
  parsedData.value.splice(index, 1);
  
  ElMessage.success('已删除行');
};

// 添加处理LRC文件上传的函数
const handleLrcUpload = (file) => {
  if (!file) return;
  
  // 检查文件类型
  if (!file.raw.name.toLowerCase().endsWith('.lrc')) {
    ElMessage.error('请上传LRC格式的歌词文件');
    return;
  }
  
  // 首先将文件读取为ArrayBuffer以检测编码
  const bufferReader = new FileReader();
  
  bufferReader.onload = async (e) => {
    const buffer = e.target.result;
    const bytes = new Uint8Array(buffer);
    
    // 检测编码
    let encoding = 'UTF-8'; // 默认假设是UTF-8
    
    // 检查BOM标记
    if (bytes.length >= 3 && bytes[0] === 0xEF && bytes[1] === 0xBB && bytes[2] === 0xBF) {
      encoding = 'UTF-8'; // 有UTF-8 BOM
    } else if (bytes.length >= 2 && bytes[0] === 0xFE && bytes[1] === 0xFF) {
      encoding = 'UTF-16BE';
    } else if (bytes.length >= 2 && bytes[0] === 0xFF && bytes[1] === 0xFE) {
      encoding = 'UTF-16LE';
    } else {
      // 没有BOM标记，需要进一步分析
      // 检查是否有汉字编码特征
      let hasHighByteChars = false;
      let hasGBKChars = false;
      
      for (let i = 0; i < bytes.length - 1; i++) {
        // 检查高字节
        if (bytes[i] > 0x7F) {
          hasHighByteChars = true;
          
          // 检查是否可能是GBK/GB2312
          if (bytes[i] >= 0x81 && bytes[i] <= 0xFE && 
              bytes[i+1] >= 0x40 && bytes[i+1] <= 0xFE) {
            hasGBKChars = true;
          }
        }
      }
      
      if (hasGBKChars) {
        encoding = 'GBK';
      } else if (hasHighByteChars) {
        // 如果有高字节但不符合GBK特征，先尝试Big5
        encoding = 'Big5';
      }
    }
    
    // 尝试读取文件内容（使用检测到的编码）
    try {
      // 使用TextDecoder API (如果支持)
      if (window.TextDecoder) {
        let decoder;
        try {
          decoder = new TextDecoder(encoding);
          const content = decoder.decode(buffer);
          
          // 检查解码后的内容是否正常
          if (content.includes('')) {
            // 解码后仍有乱码，尝试其他编码
            ElMessage.warning(`使用${encoding}解码可能存在问题，尝试使用GBK...`);
            
            try {
              decoder = new TextDecoder('GBK');
              const gbkContent = decoder.decode(buffer);
              lyricForm.lyrics = gbkContent;
              ElMessage.success(`成功导入歌词文件(GBK): ${file.name}`);
            } catch (gbkError) {
              // GBK也不行，最后尝试Big5
              try {
                decoder = new TextDecoder('Big5');
                const big5Content = decoder.decode(buffer);
                lyricForm.lyrics = big5Content;
                ElMessage.success(`成功导入歌词文件(Big5): ${file.name}`);
              } catch (big5Error) {
                // 都不行，回退到UTF-8
                lyricForm.lyrics = content;
                ElMessage.warning(`无法确定编码，使用UTF-8导入: ${file.name}`);
              }
            }
          } else {
            // 解码正常
            lyricForm.lyrics = content;
            ElMessage.success(`成功导入歌词文件(${encoding}): ${file.name}`);
          }
        } catch (decodeError) {
          // TextDecoder不支持该编码，使用传统方式
          fallbackReadWithEncoding(file, encoding);
        }
      } else {
        // 浏览器不支持TextDecoder，使用传统方式
        fallbackReadWithEncoding(file, encoding);
      }
    } catch (error) {
      ElMessage.error(`读取文件失败: ${error.message}`);
    }
  };
  
  bufferReader.onerror = () => {
    ElMessage.error('读取文件失败');
  };
  
  // 开始读取文件为ArrayBuffer
  bufferReader.readAsArrayBuffer(file.raw);
};

// 添加回退到传统FileReader的函数
const fallbackReadWithEncoding = (file, encoding) => {
  const reader = new FileReader();
  
  reader.onload = (e) => {
    const content = e.target.result;
    
    // 检查是否有乱码
    if (content.includes('')) {
      // 有乱码，尝试其他编码
      tryAlternativeEncodings(file);
    } else {
      // 内容看起来正常
      lyricForm.lyrics = content;
      ElMessage.success(`成功导入歌词文件: ${file.name}`);
    }
  };
  
  reader.onerror = () => {
    ElMessage.error('读取文件失败');
  };
  
  // 尝试用检测到的编码读取
  try {
    reader.readAsText(file.raw, encoding);
  } catch (e) {
    // 如果指定的编码不支持，回退到UTF-8
    reader.readAsText(file.raw, 'UTF-8');
  }
};

// 尝试各种常见编码
const tryAlternativeEncodings = (file) => {
  const encodings = ['GBK', 'GB2312', 'Big5', 'UTF-8'];
  let bestContent = '';
  let bestEncoding = '';
  let leastErrors = Infinity;
  
  // 尝试所有编码，保留错误最少的结果
  const tryNextEncoding = (index) => {
    if (index >= encodings.length) {
      // 所有编码都尝试过了，使用最佳结果
      if (bestContent) {
        lyricForm.lyrics = bestContent;
        ElMessage.success(`使用最佳匹配编码(${bestEncoding})导入: ${file.name}`);
      } else {
        ElMessage.error('无法正确解析文件编码');
      }
      return;
    }
    
    const currentEncoding = encodings[index];
    const reader = new FileReader();
    
    reader.onload = (e) => {
      const content = e.target.result;
      // 修复空正则表达式，替换为检测无法显示字符的正则
      const errorCount = (content.match(/[\uFFFD\uD800-\uDBFF]|[\uDC00-\uDFFF]/g) || []).length;
      
      if (errorCount < leastErrors) {
        leastErrors = errorCount;
        bestContent = content;
        bestEncoding = currentEncoding;
      }
      
      if (errorCount === 0) {
        // 找到完美匹配，直接使用
        lyricForm.lyrics = content;
        ElMessage.success(`成功导入歌词文件(${currentEncoding}): ${file.name}`);
      } else {
        // 继续尝试下一个编码
        tryNextEncoding(index + 1);
      }
    };
    
    reader.onerror = () => {
      // 出错了，尝试下一个编码
      tryNextEncoding(index + 1);
    };
    
    try {
      reader.readAsText(file.raw, currentEncoding);
    } catch (e) {
      // 不支持该编码，尝试下一个
      tryNextEncoding(index + 1);
    }
  };
  
  // 开始尝试第一个编码
  tryNextEncoding(0);
};
</script>

<style scoped>
.lyrics-input-container {
  position: relative;
}

.upload-lrc-btn {
  position: absolute;
  top: 5px;
  right: 5px;
  z-index: 10;
}
.home-container {
  display: flex;
  gap: 20px;
  width: 100%;
  max-width: 100%;
  padding: 0;
  margin: 0;
}

.lyrics-container {
  flex: 0.5; /* 从flex: 1减小到flex: 0.5，相当于减小50% */
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  min-width: 0; /* 防止flex子项溢出 */
}

.parse-preview-container {
  flex: 1.5; /* 增加解析预览容器的比例，使其更宽 */
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  min-width: 0;
  position: relative;
}

.parameters-container {
  flex: 0.4; /* 从flex: 1减小到flex: 0.4，相当于减小60% */
  background-color: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  min-width: 0; /* 防止flex子项溢出 */
}

.empty-preview {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}

.parsed-line {
  display: flex;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px dashed #ddd;
  align-items: flex-start;
  position: relative;
}

.line-number {
  min-width: 30px;
  font-weight: bold;
  color: #909399;
  margin-top: 18px; /* 调整行号垂直位置，对齐歌词 */
  margin-right: 5px;
}

.time-container {
  display: flex;
  align-items: center;
  min-width: 280px;
  margin-right: 10px;
}

.time-capture-btn {
  margin-left: 5px;
  padding: 4px 8px;
  font-size: 12px;
}

.time-row {
  font-family: monospace;
  color: #409EFF;
  margin-top: 18px;
  min-width: 70px;
}

.end-time {
  color: #67C23A; /* 绿色，区分结束时间 */
}

.time-separator {
  margin: 0 5px;
  color: #909399;
  margin-top: 18px; /* 对齐其他元素 */
}

.line-content {
  flex: 1;
  display: flex;
  flex-direction: column;
}

.aligned-content {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.unit-grid {
  display: flex;
  flex-wrap: wrap;
}

.unit-pair {
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: 0 2px;
  min-width: 30px;
}

.pinyin-unit {
  font-size: 12px;
  color: #606266;
  margin-bottom: 2px;
  text-align: center;
}

.lyric-unit {
  font-size: 16px;
  text-align: center;
  margin-bottom: 2px;
}

.phonetic-unit {
  font-size: 16px;
  color: #E6A23C;
  text-align: center;
}

.audio-player {
  margin-top: 10px;
}

.audio-player audio {
  width: 100%;
}

.parse-preview-container h2 {
  text-align: center;
  margin-top: 0;
  margin-bottom: 20px;
}

.preview-buttons {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  gap: 10px;
}

.copy-btn {
  position: static;
}

.play-button-container {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: 8px;
}

.pinyin-play-btn {
  margin-right: 4px;
}

.time-warning {
  border: 2px solid #F56C6C;
  border-radius: 4px;
  padding: 5px;
}

.section-btn {
  margin-right: 5px;
}

.section-marker {
  position: relative;
  width: 100%;
  text-align: center;
  padding: 5px 0;
  font-weight: bold;
  font-size: 18px;
  color: #409EFF;
  background-color: #ecf5ff;
  border-radius: 4px;
  margin: 10px 0;
}

.download-progress-container {
  margin: 10px 0;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.download-logs {
  margin-top: 10px;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.log-title {
  margin-top: 0;
  margin-bottom: 10px;
}

.log-container {
  max-height: 200px;
  overflow-y: auto;
}

.log-container p {
  margin: 5px 0;
}

.log-container p.success {
  color: #67C23A;
}

.log-container p.warning {
  color: #E6A23C;
}

.log-container p.exception {
  color: #F56C6C;
}

.empty-line {
  background-color: #f8f9fa;
  border: 1px dashed #ddd;
}

.empty-line-content {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 10px;
}

.empty-line-text {
  color: #909399;
  font-style: italic;
  margin-right: 20px;
}

.empty-line-placeholder {
  color: #c0c4cc;
  font-style: italic;
}

.server-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 10px 0;
  padding: 8px;
  background-color: #f8f8f8;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.server-status .el-tag {
  margin-right: 10px;
}

@media screen and (max-width: 1200px) {
  .home-container {
    flex-direction: column;
  }
}

.delete-btn {
  margin-left: 8px;
}

.delete-section-btn {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
}
</style> 